package lib

import (
	"flag"
	"fmt"

	"gitee.com/krio/helper/logger"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

var (
	C    *Config
	file string
)

func init() {
	// flag自定义配置地址
	flag.StringVar(&file, "f", "./conf/config.yaml", "config file path")
	flag.Parse()

	viper.SetConfigFile(file)
	viper.WatchConfig()
	// 设置回调函数，当配置文件发生变化时，这个函数将被调用
	viper.OnConfigChange(func(in fsnotify.Event) {
		// 在这里处理配置文件变化后的逻辑，例如重新加载配置等。
		err := InitConfig(file)
		if err != nil {
			return
		}
		fmt.Sprintf("配置更新了")
	})
	if err := viper.ReadInConfig(); err != nil {
		logger.Panicf("read config failed, err: %v", err)
	}
	if err := viper.Unmarshal(&C); err != nil {
		logger.Panicf("config viper unmarshal failed, err: %v", err)
	}
}

func InitConfig(file string) error {
	viper.SetConfigFile(file)
	// 设置回调函数，当配置文件发生变化时，这个函数将被调用
	if err := viper.ReadInConfig(); err != nil {
		return err
	}
	if err := viper.Unmarshal(&C); err != nil {
		return err
	}
	return nil
}

// Config 配置
type Config struct {
	App             *App
	Gin             *Gin
	Logger          *Logger
	Swagger         *Swagger
	RequestValidate *RequestValidate
	Redis           *Redis
	JWT             *JWT
	GRPC            *GRPC
	Trace           *Trace
}

type AppEnv string

const (
	Dev  AppEnv = "dev"
	Pre  AppEnv = "pre"
	Prod AppEnv = "prod"
)

// App 服务相关
type App struct {
	AppID   string // 服务标识符
	AppName string // 服务名称
	AppDesc string // 服务描述
	AppEnv  AppEnv // 服务环境变量
	IsProd  bool   // 是否生产环境
}

// Gin gin框架配置
type Gin struct {
	Mode string // 模式：debug|release|test
	Port int32  // 端口
}

// Logger 日志配置
type Logger struct {
	Level    string // 错误等级： debug|info|warn|error|fatal
	Debug    bool
	FilePath string
	TraceKey []string
}

// Swagger swagger文档
type Swagger struct {
	Dir    string // 地址
	Enable bool   // 是否开启
}

// GRPC gRPC地址
type GRPC struct {
	PbAddr string
}

// JWT jwt配置
type JWT struct {
	SignKey     string
	ExpiresTime int
	Issuer      string
}

// RequestValidate 请求参数验证配置
type RequestValidate struct {
	Language string
}

// Redis redis配置
type Redis struct {
	DSN      string // URL
	Password string // 密码
	MaxIdle  int    // 最大空闲数
	DB       int    // DB
}

// Trace 链路追踪
type Trace struct {
	TraceKey string
}
